<?php

class Domain implements IDomainDefinition
{

  protected static $instance;

  protected $objects = array();

  public $repositories = array();

  /**
   *
   * @return IDomainDefinition
   */
  public static function getInstance()
  {
    if (empty(Domain::$instance)) {
      /*$cache = new SessionCache();

      try {
        Domain::$instance = $cache->read('domain');
      }
      catch (CacheException $e) {*/
        Domain::$instance = new Domain();
        /*$cache->write('domain', Domain::$instance);
      }*/
    }

    return Domain::$instance;
  }

  public function getRepository($name)
  {
    if (! isset($this->repositories[$name])) {
      throw new Exception("Unknown repository: <b>$name</b>");
    }

    return $this->repositories[$name];
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/domain/api/IDomainDefinition#getObjects()
   */
  public function getObjects()
  {
    return $this->objects;
  }

  /**
   *
   * @return void
   */
  private function __construct()
  {
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/domain/api/IDomainDefinition#addObject($name, $def)
   */
  public function addObject(IDomObjDefinition $def)
  {
    $this->objects[$def->getName()] = & $def;
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/domain/api/IDomainDefinition#getObject($name)
   */
  public function getObject($name)
  {
    if (! $this->hasObject($name)) {
      throw new DomainObjectNotFoundException("Object definition not found in domain: <b>$name</b>");
    }

    return $this->objects[$name];
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/domain/api/IDomainDefinition#hasObject($name)
   */
  public function hasObject($name)
  {
    return isset($this->objects[$name]);
  }

  /**
   *
   * @param $def
   * @return IEntityDefinition
   */
  public static function toEntity($def)
  {
    if (! is_a($def, 'IEntityDefinition')) {
      throw new DomainTypeConversionException("Could not convert to IEntityDefinition");
    }

    return $def;
  }

  /**
   *
   * @param $def
   * @return IAggregateDefinition
   */
  public static function toAggregate($def)
  {
    if (! is_a($def, 'IAggregateDefinition')) {
      throw new DomainTypeConversionException("Could not convert to IAggregateDefinition");
    }

    return $def;
  }

}

?>